<template>
  <div class="flex flex-wrap items-center">
    <el-dropdown trigger="click" @command="handleCommand">
      <el-button type="primary" @click="getIssueTransitions">
        {{ issueStatus }}
        <el-icon class="el-icon--right">
          <arrow-down />
        </el-icon>
      </el-button>
      <template #dropdown>
        <div>
          <div v-loading="loading" v-if="loading"
               style="display: flex; flex-direction: column; width: 180px; height: 200px">
          </div>
          <el-dropdown-item v-loading="loading" :command="transition" v-for="transition in issueTransitionList">
            {{ toTransitionPrefixString }}
            <StatusButton :title="transition.name" style="margin-left: 15px"></StatusButton>
          </el-dropdown-item>
        </div>
      </template>
    </el-dropdown>

    <el-dialog v-model="dialogFormVisible" title="Change Issue Status"
               :close-on-click-modal="false"
               :close-on-press-escape="false"
               :show-close="false"
               center
               width="70%">

      <el-form :model="form" :label-width="formLabelWidth">

        <el-form-item v-for="field in fieldsRequired" :key="field.name" :label="field.title">

          <el-input v-model="field.value" autocomplete="off" v-if="field.schema.type === `timetracking`" />

          <el-input v-model="field.value" autocomplete="off" v-if="field.schema.type === `string`" />

          <el-select
            v-if="field.schema.type === `user`"
            v-model="field.value"
            filterable
            remote
            @visible-change="onselectionchange(field)"
            placeholder=""
            :remote-method="remoteMethod"
            :loading="loading"
          >
            <el-option
              :autocomplete="true"
              v-for="item in options"
              :key="item.value"
              :label="item.displayName"
              :value="item.accountId"
            >
              <div display="flex">
                <el-avatar
                  size="small"
                  fit="fill"
                  :src="item.avatarUrls['32x32']"
                />
                <div style="margin-left: 10px; padding-bottom: 3px">{{ item.displayName }}</div>
              </div>
            </el-option>
          </el-select>

          <el-select
            v-if="field.schema.type === `array`"
            v-model="field.value"
            filterable
            remote
            @visible-change="onselectionchange(field)"
            placeholder=""
            :remote-method="remoteMethod"
            :loading="loading"
          >
            <el-option
              :autocomplete="true"
              v-for="item in options"
              :key="item.value"
              :label="item.displayName"
              :value="item.displayName"
            >
              <div display="flex">
                <el-avatar
                  size="small"
                  fit="fill"
                  :src="item.avatarUrls['32x32']"
                />
                <div style="margin-left: 10px; padding-bottom: 3px">{{ item.displayName }}</div>
              </div>
            </el-option>
          </el-select>

          <el-select
            v-if="field.schema.type === `option`"
            v-model="field.value"
            remote
            @visible-change="onselectionchange(field)"
            placeholder=""
            :remote-method="remoteMethod"
            :loading="loading"
          >
            <el-option
              :autocomplete="true"
              v-for="item in field.allowedValues"
              :key="item.value"
              :label="item.value"
              :value="item.id"
            >
              <div style="margin-left: 10px; padding-bottom: 3px">{{ item.value }}</div>
            </el-option>
          </el-select>
        </el-form-item>

        <el-form-item label="Add Comments" :label-width="formLabelWidth">
          <el-input :rows="3" type="textarea" v-model="form.comments" autocomplete="off" />
        </el-form-item>
      </el-form>

      <template #footer>
      <span class="dialog-footer">
        <el-button @click="dialogFormVisible = false">Cancel</el-button>
        <el-button type="primary" @click="doUpdate" :loading="updateLoading">
          Confirm
        </el-button>
      </span>
      </template>
    </el-dialog>
  </div>
</template>


<script setup lang="ts">
import { ref, reactive, defineProps } from 'vue'
import { ElMessage, ElForm, ElFormItem, ElInput, ElButton, ElDialog, ElDropdown, ElDropdownItem } from 'element-plus'
import { Transition } from '@/views/types/issues'
import { confirmUpdate, getTransitionFields, listReq, queryFields } from '@/api/dict'
import StatusButton from '@/views/jiraCompontent/StatusButton.vue'

interface FieldRequired {
  title: string;
  name: string;
  autoCompleteUrl?: string
  required: boolean
}

interface TransitionInfo {
  id: string;
  key: string;
}

interface InputFieldInfo {
  autoCompleteUrl: string
  key: string
  name: string
  operations: string[],
  required: false,
  schema: {
    custom: string,
    customId: number,
    type: string
  }
}

let loading = ref(true)
let updateLoading = ref(false)
let formLabelWidth = ref('190px')
let dialogFormVisible = ref(false)

let form = reactive({ comments: '' })
let fieldsRequired = ref<FieldRequired[]>([])
let transitionInfo = ref<TransitionInfo>({ id: '0', key: 'ZOOM-000000' })

let inputFieldInfo = ref<InputFieldInfo>({
  'autoCompleteUrl': '',
  'key': '',
  'name': '',
  'operations': [
    'set'
  ],
  'required': false,
  'schema': {
    'custom': '',
    'customId': 0,
    type: ''
  }
})

const transitionBody = {
  'fields': {},
  'transition': {
    'id': ''
  },
  'update': {}
}

let issueTransitionList = ref<Array<Transition>>([])
const toTransitionPrefixString = '->'
let options = ref<Array<{}>>([])


async function getIssueTransitions() {
  loading.value = true
  issueTransitionList.value = []
  try {
    const resp = await listReq({ issueKey: props.issueKey })
    issueTransitionList.value = resp.data['transitions']
  } finally {
    loading.value = false
  }
}

const props = defineProps({
  issueStatus: {
    type: String,
    required: true
  },
  issueKey: {
    key: String,
    required: true
  }
})

async function handleCommand(e: Transition) {
  transitionInfo.value.id = String(e.id)
  transitionInfo.value.key = String(e.name)

  const resp = await getTransitionFields({
    'issueKey': props.issueKey,
    'toTransitionId': e.id
  })

  const fields = resp.data.transitions[0]?.fields || null
  fieldsRequired.value = Object.values(fields || {})
    .filter((field: any) => field.key !== 'assignee') // Exclude fields with name "test"
    .map((field: any) => ({
      title: field.name,
      name: field.key,
      required: field.required,
      autoCompleteUrl: field.autoCompleteUrl,
      schema: field.schema,
      allowedValues: field.allowedValues
    }))

  if (fieldsRequired.value.length !== 0) {
    // Need Popup a Form to let user input or select some fields
    dialogFormVisible.value = true
    console.log(transitionInfo.value)
  } else {
    console.log(transitionInfo.value.key)
    // No Fields Required When Change Status form A to B
    if (['Reopen'].includes(transitionInfo.value.key)) {
      dialogFormVisible.value = true
    } else {
      await doRequestUpdate()
    }
  }
}

type jiraFieldsType = 'user' | 'string' | 'timetracking'

async function remoteMethod(query) {
  console.log(query)
  console.log(inputFieldInfo.value.name)

  const fieldType = inputFieldInfo.value.schema.type

  switch (fieldType) {
    case 'user':
      loading.value = true
      const resp = await queryFields({ autoCompleteUrl: inputFieldInfo.value.autoCompleteUrl, query: query })
      if (inputFieldInfo.value.name.includes('customfield')) {
        options.value = resp.data['users']
      } else {
        options.value = resp.data
      }
      break
    case 'string':
      console.log('The value is a number.')
      break
    case 'timetracking':
      const timetracking = {
        'timetracking': {
          'remainingEstimate': '55m',
          'originalEstimate': '2h'
        }
      }
      console.log(timetracking)

      console.log('The value is a number.')
      break
    case 'option':
      console.log(inputFieldInfo.value)
      console.log('The value is a number.')
      options.value = inputFieldInfo.value.allowValues
      break
    default:
      console.log('The value is neither a string nor a number.')
  }

  loading.value = false


}

async function doUpdate() {
  updateLoading.value = true
  await doRequestUpdate()
  console.log(fieldsRequired)
  updateLoading.value = false
}


async function doRequestUpdate() {
  let fieldsValue: Record<string, any> = {}
  fieldsRequired.value.forEach((field: FieldRequired) => {
    fieldsValue[field.name] = field.value
  })

  transitionBody.fields = fieldsValue
  transitionBody.transition.id = String(transitionInfo.value.id)

  if (form.comments.length !== 0) {
    transitionBody.update = {
      'comment': [
        {
          'add': {
            'body': {
              'content': [
                {
                  'content': [
                    {
                      'text': form.comments,
                      'type': 'text'
                    }
                  ],
                  'type': 'paragraph'
                }
              ],
              'type': 'doc',
              'version': 1
            }
          }
        }
      ]
    }
  }

  try {
    const resp = await confirmUpdate({ issueKey: props.issueKey, transitionBody: transitionBody })
    console.log(resp)
    let isSuccess = resp.code === 200 ? 'success' : 'error'
    let message = resp.code === 200 ? 'update success' : resp.message
    elMessage(message, isSuccess)
    dialogFormVisible.value = false
  } finally {
    updateLoading.value = false
  }
}


function onselectionchange(query) {

  inputFieldInfo.value = query
}

</script>


<style scoped>
.demo-type {
  display: flex;
}

.demo-type > div {
  flex: 1;
  text-align: center;
}

.demo-type > div:not(:last-child) {
  border-right: 1px solid var(--el-border-color);
}
</style>
